/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package powierzchnie;

import gra.TVisualisation;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import nor.TPoint;
import out.IOut;
import ste.TAbstBlock;

/**
 *
 * @author arkadiusz
 */
public class Powierzchnie extends TAbstBlock {

    private ArrayList<TPoint[]> fPtTAL = new ArrayList<TPoint[]>();
    //wstawienie tu Vektora pogarsza sprawe o jakies 2s. :-(
    private ArrayList<SpojnyObszar> tabSObszary = new ArrayList<SpojnyObszar>();
    
    private int prog;
    private int maxKatStopnie;
    private double minOdlegosc;
    private boolean czyDopasowywac = false;
    
    @Override
    public String getTabTitle() {
        return "Powierzchnie etap 1";
    }

    @Override
    public JComponent getJComponent() {
        return new PowierzchniePanel(this);
    }

    @Override
    public void setNext(TAbstBlock aNext) {
    }

    @Override
    public void checkSettings() {
    }

    @Override
    public void showGraphic() {
        System.out.println("Rozmiar tablicy: " + this.tabSObszary.size());

        TVisualisation _lVis = new TVisualisation(); //do grafiki
        
        Collections.sort(this.tabSObszary);
        
        Color kMax = new Color(200,200,200);
        int min = Math.min(1000000, this.tabSObszary.size());
        
        for (int i = 0; i <  min ; i++) {
            SpojnyObszar so = this.tabSObszary.get(i);
            Color kObsz = new Color(i * kMax.getRGB() /this.tabSObszary.size() );
            so.setColor(kObsz);
            _lVis.addPtNorT(
                    so.getAL().toArray(new TPoint[so.size()]));

        }

        _lVis.display();
    }

    @Override
    public void clear() {
    }

    @Override
    public void starter(IOut o) {
        // wrzystko w metdzie finish
    }

    @Override
    public void finish() {
        //dla optymalizacji mierze czas
        long start = System.currentTimeMillis();
        try {
            //dodajemy pierwszy obszar na podstawie pierwszego punktu
            this.tabSObszary.add(new SpojnyObszar(this.fPtTAL.get(1)[1], this.maxKatStopnie, this.minOdlegosc));
        } catch(Exception ex) {
            Logger.getLogger(Powierzchnie.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex);
        }

        //przegladamy punkt po punkcie...
        //for(TPoint[] tabTPoint : this.fPtTAL){
        //ale bez pierwszego i ostatniego, bo dla nich nie ma policzonych normalnych
        for (int i = 1; i < this.fPtTAL.size() - 1; i++) {
            TPoint[] tabTPoint = this.fPtTAL.get(i);

           //System.out.println("this.tabSObszary.size(): " + this.tabSObszary.size());
            //jak wyzej tj. bez pierwszego i ostatiniego
            //for(TPoint p : tabTPoint) {//x
            for (int j = 1; j < tabTPoint.length - 1; j++) {//x

                TPoint p = tabTPoint[j];

                boolean czyDodacNowyObszar = true;
                //...i kazdy punkt sprawdzamy czy nie nalezy do jakiegos obszaru
                //(przegladamy od konca by przyspieszyc algorytm) (oby)
                //wyniki testu: stara wersja ~ 18min (dla schodow przy windzie)
                //               nowa wersja ~ 3min (dla schodow przy windzie)
//                for ( SpojnyObszar obszar : this.tabSObszary ){
                for (int ii = this.tabSObszary.size()-1; ii >=0; ii--){
                    SpojnyObszar obszar = this.tabSObszary.get(ii); 
                    // (probujemy dodac ale jezeli sie nie uda to...
                    boolean czyDodane = obszar.add(p);

                    if (czyDodane) {
                        czyDodacNowyObszar = false;
                        break;
                    }

                }
                if (czyDodacNowyObszar) {
                    try {
                        this.tabSObszary.add(new SpojnyObszar(p, this.maxKatStopnie, this.minOdlegosc));
                    } catch(Exception ex) {
                        //Logger.getLogger(Powierzchnie.class.getName()).log(Level.SEVERE, null, ex);
                        //System.out.println(ex);
                        System.err.println("!!!wyjatek!!!");
                    }
                }
            }//x

        }
        //dla optymalizacji mierze czas
        long stop = System.currentTimeMillis();
        
        
        System.out.println("czas wykonania: " + (stop - start)/1000.0 + "s" );
      
        //czyscimy tablice z punktow
       this.czyscTabSObszary(this.getProg());
        
        //System.out.println("this.tabSObszary.size(): " + this.tabSObszary.size());
       
       //dopasowyjemy odpowiednie plaszczyzny
        String wy = this.obliczDopasowanie();
        if(this.isCzyDopasowywac()) 
          new WyjsceFrame( wy ).setVisible(true);
        
        
        this.liczBrzegi();

    }
    //Do przekazania całej tablicy punktów (bo nie korzystam ze startera)

    public void setPtTAL(ArrayList<TPoint[]> aPtTAL) {
        this.fPtTAL = aPtTAL;

    } //koniec setPtTAL
    
    
    public void czyscTabSObszary(int prog){
    
        int ii = 0;
        int liczbaPonizejProgu = 0;
        Iterator it = this.tabSObszary.iterator();
        
        while (it.hasNext()) {
            SpojnyObszar sp = (SpojnyObszar) it.next();
            if (sp.size() <= prog) {
                liczbaPonizejProgu++;
                it.remove();
            }
                //System.out.println("this.tabSObszary[" + ii++ + "] = " + sp.size());
        }
        System.out.println("Liczba Obszarow ponizej progu: " + liczbaPonizejProgu);
    
    }
    
    public String obliczDopasowanie(){
        String wy;
        wy = "kat=;" + this.maxKatStopnie + "; odl=;" + this.minOdlegosc + "; prog=;" + this.prog +"\n";
        wy += "[A;B;C;D]; Rozmiar; Sr Odl; Sr Blad Kw \n";
       for (SpojnyObszar sp : this.tabSObszary){
         wy += sp.getPlaszczyzna() + "; " 
            + sp.size() + "; " +
            + sp.liczBladSrOdleglosc() + "; " 
            + sp.liczBladSrBladKw() +  "\n "; 
            
           
       }
       return wy;
    }
    

    public int getProg() {
        return prog;
    }

    public void setProg(int prog) {
        this.prog = prog;
    }

    public int getMaxKatStopnie() {
        return maxKatStopnie;
    }

    public void setMaxKatStopnie(int maxKatStopnie) {
        this.maxKatStopnie = maxKatStopnie;
    }

    public double getMinOdlegosc() {
        return minOdlegosc;
    }

    public void setMinOdlegosc(double minOdlegosc) {
        this.minOdlegosc = minOdlegosc;
    }

    public boolean isCzyDopasowywac() {
        return czyDopasowywac;
    }

    public void setCzyDopasowywac(boolean czyDopasowywac) {
        this.czyDopasowywac = czyDopasowywac;
    }

    private void liczBrzegi() {
       
    }
}
